package fr.pud.client.model;

import java.io.Serializable;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import fr.pud.utils.DOMParser;

/**
 * A class which create an object time represented with hours and minutes
 * Apr 9, 2012 - OSE.
 * @author Simon Devineau, Adrien Hierry, Leopold Houdin, Pierre Reliquet
 *         Ecole des Mines de Nantes
 *         Time.java
 */
public class Time implements Serializable {
    /**
     * The serial UID
     */
    private static final long serialVersionUID = 8404478987505200503L;
    /**
     * Hours
     */
    private int               hours;
    /**
     * Minutes
     */
    private int               minutes;

    /**
     * Default constructor which initializes to 0:00
     */
    public Time() {
        this(0, 0);
    }

    /**
     * @param m
     *            the minutes which are converted into hours and minutes.
     */
    public Time(int m) {
        if ((m + "").length() != 4) {
            this.initialize(m / 60, m % 60);
        }
        else {
            this.initialize(m / 100, m % 100);
        }
    }

    /**
     * @param h
     *            the hours
     * @param m
     *            the minutes
     */
    public Time(int h, int m) {
        this.initialize(h, m);
    }

    /**
     * Format accepted 8:00 / 8h00 / 8H00.
     * @param t
     *            a String representation of the hours which is converted to
     *            hours & minutes.
     */
    public Time(String t) {
        this(Integer.parseInt(t.split(":|h|H")[0]), Integer.parseInt(t
                .split(":|h|H")[1]));
    }

    /**
     * @param obj
     *            an object.
     * @return true if obj is equal to this.
     */
    @Override
    public boolean equals(Object obj) {
        if (obj instanceof Time) {
            Time o = (Time) obj;
            return o.getHours() == this.getHours()
                    && o.getMinutes() == this.getMinutes();
        }
        return false;
    }

    /**
     * @return a representation in minutes.
     */
    public int getFullMinutes() {
        return this.hours * 60 + this.minutes;
    }

    /**
     * @return a representation in seconds.
     */
    public int getFullSeconds() {
        return 60 * this.getFullMinutes();
    }

    /**
     * @return the hours.
     */
    public int getHours() {
        return this.hours;
    }

    /**
     * @return the minutes.
     */
    public int getMinutes() {
        return this.minutes;
    }

    /**
     * Checks if the minutes are less than 60 and hours less than 24.
     * @param h
     *            the hours.
     * @param m
     *            the minutes.
     */
    private void initialize(int h, int m) {
        if (h >= 0 && h < 24) {
            this.hours = h;
        }
        else {
            this.hours = 0;
        }
        if (m < 60 && m >= 0) {
            this.minutes = m;
        }
        else {
            this.minutes = 0;
        }
    }

    /**
     * @param hours
     *            the new hour
     */
    public void setHours(int hours) {
        this.hours = hours;
    }

    /**
     * @param minutes
     *            the new minutes.
     */
    public void setMinutes(int minutes) {
        this.minutes = minutes;
    }

    /**
     * @return a string representation.
     */
    @Override
    public String toString() {
        if (this.minutes == 0) {
            return this.getHours() + ":00";
        }
        else {
            return this.getHours() + ":" + this.getMinutes();
        }
    }

    /**
     * @param d
     *            the document where the xml representation is supposed to be
     *            bound.
     * @return A string representation bounded to the document d.
     */
    public Element toXML(Document d) {
        return this.toXML(d, "Time");
    }

    /**
     * @param d
     *            the document where the xml representation is supposed to be
     *            bound.
     * @param name
     *            the root name.
     * @return A string representation bounded to the document d.
     */
    public Element toXML(Document d, String name) {
        Element root = d.createElement(name);
        DOMParser.getElementAppended(d, "Hours", "" + this.getHours(), root);
        DOMParser
                .getElementAppended(d, "Minutes", "" + this.getMinutes(), root);
        return root;
    }
}
